package com.htfyun.factorytest.common;

import android.content.Context;
import android.provider.Settings;
import android.util.Log;

import com.blankj.utilcode.util.FileIOUtils;
import com.htfyun.factorytest.config.EinkProperty;

/**
 * 20181124: 控制 EINK 前光。我们在背光的基础上进行扩展。
 */
public class ForeLightCtrl {

    /*
     * 20181127: 最大背光改为 63(0X3F),这样每个背光用 6BIT 来表示。冷光和暖光就不会丢失信息了。
     */

    private static final String TAG = "ForeLightCtrl";
    private static boolean DBG = true;

    private static final int WARM_BRIGHTNESS_BITS = 0;
    private static final int COLD_BRIGHTNESS_BITS = 6;

    private static final int BRIGHTNESS_MASK = 0X3F;

    private static final int WARM_ON_MASK = (0X01 << 12);
    private static final int COLD_ON_MASK = (0X01 << 13);

    private static final int COMPLEX_BRIGHTNESS_MASK = (0X3FFF);

    private static int mBrightness = -1;
    private static int mSettingBrightness = -1;

    private static final String BRIGHTNESS_PATH = "/sys/class/backlight/ht_eink_fl/brightness";
    private static final String PROPERTY_EINK_LIGHT_MODE = "persist.eink_light.mode";

    private static final String BRIGHTNESS_COLD_PATH = "/sys/class/backlight/backlight-cold/brightness";
    private static final String BRIGHTNESS_WARM_PATH = "/sys/class/backlight/backlight-warm/brightness";
    private static final int BRIGHTNESS_MAX = 255;

    public static void setColdBrightMax(Context ctx) {
/*        SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.WARM_MODE);
        Settings.System.putInt(ctx.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS,
                0
        );
        SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.COLD_MODE);
        Settings.System.putInt(ctx.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS,
                4095
        );*/
        if (EinkProperty.isPan6()) {
            FileIOUtils.writeFileFromString(BRIGHTNESS_COLD_PATH, String.valueOf(BRIGHTNESS_MAX));
            return;
        }
        setLightBrightness(ctx, 0, BRIGHTNESS_MASK);
//        setLightOnOff(ctx, false, true);
    }

    public static void setWarmBrightMax(Context ctx) {
/*        SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.COLD_MODE);
        Settings.System.putInt(ctx.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS,
                0
        );
        SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.WARM_MODE);
        Settings.System.putInt(ctx.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS,
                4095
        );*/
        if (EinkProperty.isPan6()) {
            FileIOUtils.writeFileFromString(BRIGHTNESS_WARM_PATH, String.valueOf(BRIGHTNESS_MAX));
            return;
        }
        setLightBrightness(ctx, BRIGHTNESS_MASK, 0);
//        setLightOnOff(ctx, true, false);
    }

    public static void setBrightMiddle(Context ctx) {
/*        SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.COLD_MODE);
        Settings.System.putInt(ctx.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS,
                4095 / 2
        );
        SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.WARM_MODE);
        Settings.System.putInt(ctx.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS,
                4095 / 2
        );*/
        if (EinkProperty.isPan6()) {
            FileIOUtils.writeFileFromString(BRIGHTNESS_COLD_PATH, String.valueOf(BRIGHTNESS_MAX / 2));
            FileIOUtils.writeFileFromString(BRIGHTNESS_WARM_PATH, String.valueOf(BRIGHTNESS_MAX / 2));
            return;
        }
        setLightBrightness(ctx, BRIGHTNESS_MASK / 2, BRIGHTNESS_MASK / 2);
//        setLightOnOff(ctx, true, true);
    }

    public static void setBrightMin(Context ctx) {
/*        int brightness = Settings.System.getIntForUser(ctx.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0, UserHandle.USER_CURRENT);
        brightness = (brightness & 0xFC0) > 0 ? ((((brightness >> 0x06) - 1) << 0x06) | (brightness & 0x3F)) : 0;
        String last_mode = SystemProperties.get(PROPERTY_EINK_LIGHT_MODE);
        if (Constants.COLD_MODE.equals(last_mode)) {
            SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.COLD_OFF);
        } else if (Constants.WARM_MODE.equals(last_mode)) {
            brightness = (brightness & 0x3F) > 0 ? (((brightness & 0X3F) - 1) | (brightness & 0xFC0)) : 0;
            SystemProperties.set(PROPERTY_EINK_LIGHT_MODE, Constants.WARM_OFF);
        }
        Settings.System.putInt(ctx.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS,
                brightness
        );*/
        if (EinkProperty.isPan6()) {
            FileIOUtils.writeFileFromString(BRIGHTNESS_COLD_PATH, "0");
            FileIOUtils.writeFileFromString(BRIGHTNESS_WARM_PATH, "0");
            return;
        }
        setLightOnOff(ctx, false, false);
    }

    private static void updateBrightnessIfNeed(Context ctx) {
        if (mBrightness == -1) {
            mBrightness = Settings.System.getInt(ctx.getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS,
                    0);
            mSettingBrightness = mBrightness;
            if (DBG) Log.d(TAG, "get SCREEN_BRIGHTNESS=" + mBrightness);
        }
    }

    // 20220601: 返回系统可以支持的冷光和暖光的最大等级。有效的等级就是 0--max。
    public static int getMaxBrightness() {
        return BRIGHTNESS_MASK;
    }

    private static void setBrightness(Context ctx) {
        if (DBG) Log.d(TAG, "set SCREEN_BRIGHTNESS=" + mBrightness
                + ",setting=" + mSettingBrightness);
        if (mSettingBrightness != mBrightness) {
            Settings.System.putInt(ctx.getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS,
                    mBrightness
            );
            mSettingBrightness = mBrightness;
        }
    }

    public static int getColdBrightness(Context ctx) {
        updateBrightnessIfNeed(ctx);
        return (mBrightness >> COLD_BRIGHTNESS_BITS) & BRIGHTNESS_MASK;
    }

    public static int getWarmBrightness(Context ctx) {
        updateBrightnessIfNeed(ctx);
        return (mBrightness >> WARM_BRIGHTNESS_BITS) & BRIGHTNESS_MASK;
    }

    public static boolean isWarmOn(Context ctx) {
        updateBrightnessIfNeed(ctx);
        return (mBrightness & WARM_ON_MASK) != 0;
    }

    public static boolean isColdOn(Context ctx) {
        updateBrightnessIfNeed(ctx);
        return (mBrightness & COLD_ON_MASK) != 0;
    }

    // 20220601: 可以同时设置暖光和冷光的开关。这个函数不会修改原来的亮度值。
    public static void setLightOnOff(Context ctx, boolean warmOn, boolean coldOn) {
        updateBrightnessIfNeed(ctx);
        if (DBG) Log.d(TAG, "set setLightOnOff:warmOn=" + warmOn + ",coldOn=" + coldOn
                + ",brightness=" + mBrightness);
        if (warmOn) {
            mBrightness |= WARM_ON_MASK;
        } else {
            mBrightness &= ~WARM_ON_MASK;
        }

        if (coldOn) {
            mBrightness |= COLD_ON_MASK;
        } else {
            mBrightness &= ~COLD_ON_MASK;
        }

        setBrightness(ctx);
    }

    /**
     * 20220601: 设置前光亮度的接口。如果传入的值是-1，则不修改当前的对应前光的值。设置为0也会关闭背光，但是不会修改 warmOn/coldOn。
     * 每个背光值的有效范围是 0-63. 如果设置的背光值 > 0, 这个函数会自动打开背光。
     *
     * @param ctx
     * @param warmBrightness -1：don't change, 0: close, max: 63.
     * @param coldBrightness -1：don't change, 0: close, max: 63.
     */
    public static void setLightBrightness(Context ctx, int warmBrightness, int coldBrightness) {
        updateBrightnessIfNeed(ctx);
        if (warmBrightness >= 0) {
            warmBrightness &= BRIGHTNESS_MASK;
            mBrightness &= ~(BRIGHTNESS_MASK << WARM_BRIGHTNESS_BITS);
            mBrightness |= warmBrightness << WARM_BRIGHTNESS_BITS;

            if (warmBrightness > 0) {
                mBrightness |= WARM_ON_MASK;
            }
        }

        if (coldBrightness >= 0) {
            coldBrightness &= BRIGHTNESS_MASK;
            mBrightness &= ~(BRIGHTNESS_MASK << COLD_BRIGHTNESS_BITS);
            mBrightness |= coldBrightness << COLD_BRIGHTNESS_BITS;
            if (coldBrightness > 0) {
                mBrightness |= COLD_ON_MASK;
            }
        }

        setBrightness(ctx);
    }

    public static int getComplexLightBrightness(Context ctx) {
        updateBrightnessIfNeed(ctx);
        return mBrightness;
    }

    // 20220601：完全由应用自己控制两路背光的开关和亮度。
    public static void setComplexLightBrightness(Context ctx, int complexBrightness) {
//    	updateBrightnessIfNeed(ctx);
        if (complexBrightness >= 0) {
            mBrightness = complexBrightness & COMPLEX_BRIGHTNESS_MASK;
            setBrightness(ctx);
        }
    }

    // 20220601：复位背光，两路都关闭，且背光值都设置为0.
    public static void resetLightBrightness(Context ctx) {
        mBrightness = 0;
        setBrightness(ctx);
    }

}
